﻿using GenSpringCloudProject.projectconfig;
using MyTech.CodeGenerator.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GenSpringCloudProject.subproject.module
{
    class Module
    {
        public static bool Gen(ProjectConfig projectConfig, string basePath)
        {
            basePath = basePath + "//modules//";
            string packagePath = projectConfig.groupId.Replace(".", "//");
            FileUtil.SaveCode(basePath + "/pom.xml", GenModulesPom(projectConfig, basePath).ToString());

            //string basePomPath = basePath + projectConfig.artifactId + "//";
            //FileUtil.SaveCode(basePomPath + "/pom.xml", GenPom(projectConfig, basePath).ToString());

            //string servicePath = basePath + projectConfig.artifactId + "//" + projectConfig.artifactId + "-service//";
            //FileUtil.SaveCode(servicePath + "/pom.xml", GenServicePom(projectConfig, basePath).ToString());
            //FileUtil.SaveCode(servicePath + "//src//main//java//" + packagePath + "//configserver//ConfigServerApplication.java", GenServiceApplication().ToString());
            //FileUtil.SaveCode(servicePath + "//src//main//resources//" + "//application.yml", GenServiceApplicationYml().ToString());

            //string webPath = basePath + projectConfig.artifactId + "//" + projectConfig.artifactId + "-web//";
            //FileUtil.SaveCode(webPath + "/pom.xml", GenWebPom().ToString());
            //FileUtil.SaveCode(webPath + "//src//main//java//" + packagePath + "//configserver//ConfigServerApplication.java", GenWebApplication().ToString());
            //FileUtil.SaveCode(webPath + "//src//main//resources//" + "//application.yml", GenWebApplicationYml().ToString());

            string servicePath = basePath + "//" + projectConfig.artifactId + "-service//";
            FileUtil.SaveCode(servicePath + "/pom.xml", GenServicePom(projectConfig, basePath).ToString());
            FileUtil.SaveCode(servicePath + "//src//main//java//" + packagePath + "//" + projectConfig.artifactId.ToLower() + "service//" + UnderscoreCamelUtil.ToPascalCase(projectConfig.artifactId) + "ServiceApplication.java", GenServiceApplication(projectConfig, basePath).ToString());
            FileUtil.SaveCode(servicePath + "//src//main//java//" + packagePath + "//" + projectConfig.artifactId.ToLower() + "service//controller//HiController.java", GenServiceHiController(projectConfig, basePath).ToString());
            FileUtil.SaveCode(servicePath + "//src//main//resources//" + "//application.yml", GenServiceApplicationYml(projectConfig, basePath).ToString());

            string webPath = basePath + "//" + projectConfig.artifactId + "-web//";
            FileUtil.SaveCode(webPath + "/pom.xml", GenWebPom(projectConfig, basePath).ToString());
            FileUtil.SaveCode(webPath + "//src//main//java//" + packagePath + "//"+ projectConfig.artifactId.ToLower() + "web//" + UnderscoreCamelUtil.ToPascalCase(projectConfig.artifactId) + "WebApplication.java", GenWebApplication(projectConfig, basePath).ToString());
            FileUtil.SaveCode(webPath + "//src//main//java//" + packagePath + "//" + projectConfig.artifactId.ToLower() + "web//controller//HiController.java", GenWebHiController(projectConfig, basePath).ToString());
            FileUtil.SaveCode(webPath + "//src//main//java//" + packagePath + "//" + projectConfig.artifactId.ToLower() + "web//service//HiService.java", GenWebHiService(projectConfig, basePath).ToString());

            FileUtil.SaveCode(webPath + "//src//main//resources//" + "//application.yml", GenWebApplicationYml(projectConfig, basePath).ToString());

            return true;
        }



        public static StringBuilder GenModulesPom(ProjectConfig projectConfig, string basePath)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            sb.AppendLine("<project xmlns=\"http://maven.apache.org/POM/4.0.0\"");
            sb.AppendLine("         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
            sb.AppendLine("         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">");
            sb.AppendLine("    <parent>");
            sb.AppendLine("        <artifactId>"+ projectConfig.projectName + "</artifactId>");
            sb.AppendLine("        <groupId>" + projectConfig.groupId + "</groupId>");
            sb.AppendLine("        <version>" + projectConfig.version + "</version>");
            sb.AppendLine("    </parent>");
            sb.AppendLine("    <modelVersion>4.0.0</modelVersion>");
            sb.AppendLine("");
            sb.AppendLine("    <artifactId>modules</artifactId>");
            sb.AppendLine("    <groupId>" + projectConfig.groupId + "</groupId>");
            sb.AppendLine("    <version>" + projectConfig.version + "</version>");
            sb.AppendLine("    <packaging>pom</packaging>");
            sb.AppendLine("");
            sb.AppendLine("    <modules>");
            sb.AppendLine("        <module>" + projectConfig.artifactId + "-service</module>");
            sb.AppendLine("        <module>" + projectConfig.artifactId + "-web</module>");
            sb.AppendLine("    </modules>");
            sb.AppendLine("");
            sb.AppendLine("</project>");



            return sb;
        }

        public static StringBuilder GenPom(ProjectConfig projectConfig, string basePath)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            sb.AppendLine("<project xmlns=\"http://maven.apache.org/POM/4.0.0\"");
            sb.AppendLine("         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
            sb.AppendLine("         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">");
            sb.AppendLine("    <parent>");
            sb.AppendLine("        <artifactId>modules</artifactId>");
            sb.AppendLine("        <groupId>" + projectConfig.groupId + "</groupId>");
            sb.AppendLine("        <version>" + projectConfig.version + "</version>");
            sb.AppendLine("    </parent>");
            sb.AppendLine("    <modelVersion>4.0.0</modelVersion>");
            sb.AppendLine("");
            sb.AppendLine("    <artifactId>" + projectConfig.artifactId + "</artifactId>");
            sb.AppendLine("    <groupId>" + projectConfig.groupId + "</groupId>");
            sb.AppendLine("    <version>" + projectConfig.version + "</version>");
            sb.AppendLine("    <packaging>pom</packaging>");
            sb.AppendLine("");
            sb.AppendLine("    <modules>");
            sb.AppendLine("        <module>" + projectConfig.artifactId + "-service</module>");
            sb.AppendLine("        <module>" + projectConfig.artifactId + "-web</module>");
            sb.AppendLine("    </modules>");

            sb.AppendLine("");
            sb.AppendLine("</project>");


            return sb;
        }

        public static StringBuilder GenServicePom(ProjectConfig projectConfig, string basePath)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            sb.AppendLine("<project xmlns=\"http://maven.apache.org/POM/4.0.0\"");
            sb.AppendLine("         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
            sb.AppendLine("         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">");
            sb.AppendLine("    <parent>");
            //sb.AppendLine("        <artifactId>" + projectConfig.artifactId + "</artifactId>");
            sb.AppendLine("        <artifactId>" + "modules" + "</artifactId>");
            sb.AppendLine("        <groupId>" + projectConfig.groupId + "</groupId>");
            sb.AppendLine("        <version>" + projectConfig.version + "</version>");
            sb.AppendLine("    </parent>");
            sb.AppendLine("    <modelVersion>4.0.0</modelVersion>");
            sb.AppendLine("");
            sb.AppendLine("    <artifactId>" + projectConfig.artifactId + "-service</artifactId>");
            sb.AppendLine("    <groupId>" + projectConfig.groupId + "</groupId>");
            sb.AppendLine("    <version>" + projectConfig.version + "</version>");
            sb.AppendLine("    <packaging>jar</packaging>");
            sb.AppendLine("");
            sb.AppendLine("");
            sb.AppendLine("    <dependencies>");
            sb.AppendLine("        <dependency>");
            sb.AppendLine("            <groupId>org.springframework.cloud</groupId>");
            sb.AppendLine("            <artifactId>spring-cloud-starter-eureka</artifactId>");
            sb.AppendLine("        </dependency>");
            sb.AppendLine("");
            sb.AppendLine("        <dependency>");
            sb.AppendLine("            <groupId>org.springframework.cloud</groupId>");
            sb.AppendLine("            <artifactId>spring-cloud-netflix-eureka-client</artifactId>");
            sb.AppendLine("        </dependency>");
            sb.AppendLine("");
            sb.AppendLine("        <dependency>");
            sb.AppendLine("            <groupId>org.springframework.boot</groupId>");
            sb.AppendLine("            <artifactId>spring-boot-starter-web</artifactId>");
            sb.AppendLine("        </dependency>");
            sb.AppendLine("");
            sb.AppendLine("        <!-- spring boot test-->");
            sb.AppendLine("        <dependency>");
            sb.AppendLine("            <groupId>org.springframework.boot</groupId>");
            sb.AppendLine("            <artifactId>spring-boot-starter-test</artifactId>");
            sb.AppendLine("            <scope>test</scope>");
            sb.AppendLine("        </dependency>");
            sb.AppendLine("    </dependencies>");

            sb.AppendLine("</project>");


            return sb;
        }

        private static StringBuilder GenServiceApplication(ProjectConfig projectConfig, string basePath)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("package com.ydtech." + projectConfig.artifactId.ToLower() + "service;");
            sb.AppendLine("");
            sb.AppendLine("import org.springframework.boot.SpringApplication;");
            sb.AppendLine("import org.springframework.boot.autoconfigure.SpringBootApplication;");
            sb.AppendLine("import org.springframework.cloud.client.loadbalancer.LoadBalanced;");
            sb.AppendLine("import org.springframework.cloud.netflix.eureka.EnableEurekaClient;");
            sb.AppendLine("import org.springframework.cloud.netflix.hystrix.EnableHystrix;");
            sb.AppendLine("import org.springframework.context.annotation.Bean;");
            sb.AppendLine("import org.springframework.web.client.RestTemplate;");
            sb.AppendLine("");
            sb.AppendLine("@SpringBootApplication");
            sb.AppendLine("@EnableEurekaClient");
            sb.AppendLine("public class " + UnderscoreCamelUtil.ToPascalCase(projectConfig.artifactId) + "ServiceApplication {");
            sb.AppendLine("    public static void main(String[] args) {");
            sb.AppendLine("        SpringApplication.run(" + UnderscoreCamelUtil.ToPascalCase(projectConfig.artifactId) + "ServiceApplication.class, args);");
            sb.AppendLine("    }");
            sb.AppendLine("");
            sb.AppendLine("}");
            sb.AppendLine("");


            return sb;
        }

        private static StringBuilder GenServiceHiController(ProjectConfig projectConfig, string basePath)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("package com.ydtech." + projectConfig.artifactId.ToLower() + "service.controller;");
            sb.AppendLine("");
            sb.AppendLine("import org.springframework.beans.factory.annotation.Value;");
            sb.AppendLine("import org.springframework.web.bind.annotation.GetMapping;");
            sb.AppendLine("import org.springframework.web.bind.annotation.PathVariable;");
            sb.AppendLine("import org.springframework.web.bind.annotation.RestController;");
            sb.AppendLine("");
            sb.AppendLine("@RestController");
            sb.AppendLine("public class HiController {");
            sb.AppendLine("    @Value(\"${server.port}\")");
            sb.AppendLine("    String port;");
            sb.AppendLine("");
            sb.AppendLine("    @GetMapping(\"/hi/{userName}\")");
            sb.AppendLine("    public String sayHi(@PathVariable(\"userName\") String userName){");
            sb.AppendLine("        return \"hi \" + userName + \", greeting from \" + port;");
            sb.AppendLine("    }");
            sb.AppendLine("}");
            sb.AppendLine("");



            return sb;
        }

        public static StringBuilder GenServiceApplicationYml(ProjectConfig projectConfig, string basePath)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("server:");
            sb.AppendLine("  port: 18040");
            sb.AppendLine("");
            sb.AppendLine("eureka:");
            sb.AppendLine("  client:");
            sb.AppendLine("    service-url:");
            sb.AppendLine("      defaultZone: http://localhost:8020/eureka/");
            sb.AppendLine("");
            sb.AppendLine("spring:");
            sb.AppendLine("  application:");
            sb.AppendLine("    name: " + projectConfig.artifactId.ToLower() + "-service");
            sb.AppendLine("");

            return sb;
        }


        public static StringBuilder GenWebPom(ProjectConfig projectConfig, string basePath)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            sb.AppendLine("<project xmlns=\"http://maven.apache.org/POM/4.0.0\"");
            sb.AppendLine("         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
            sb.AppendLine("         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">");
            sb.AppendLine("    <parent>");
            sb.AppendLine("        <artifactId>modules</artifactId>");
            sb.AppendLine("        <groupId>" + projectConfig.groupId + "</groupId>");
            sb.AppendLine("        <version>" + projectConfig.version + "</version>");
            sb.AppendLine("    </parent>");
            sb.AppendLine("    <modelVersion>4.0.0</modelVersion>");
            sb.AppendLine("");
            sb.AppendLine("    <artifactId>" + projectConfig.artifactId + "-web</artifactId>");
            sb.AppendLine("    <groupId>" + projectConfig.groupId + "</groupId>");
            sb.AppendLine("    <version>" + projectConfig.version + "</version>");
            sb.AppendLine("    <packaging>jar</packaging>");
            sb.AppendLine("");
            sb.AppendLine("");
            sb.AppendLine("    <dependencies>");
            sb.AppendLine("        <dependency>");
            sb.AppendLine("            <groupId>org.springframework.cloud</groupId>");
            sb.AppendLine("            <artifactId>spring-cloud-starter-eureka</artifactId>");
            sb.AppendLine("        </dependency>");
            sb.AppendLine("        <dependency>");
            sb.AppendLine("            <groupId>org.springframework.cloud</groupId>");
            sb.AppendLine("            <artifactId>spring-cloud-netflix-eureka-client</artifactId>");
            sb.AppendLine("        </dependency>");
            sb.AppendLine("");
            sb.AppendLine("        <dependency>");
            sb.AppendLine("            <groupId>org.springframework.boot</groupId>");
            sb.AppendLine("            <artifactId>spring-boot-starter-web</artifactId>");
            sb.AppendLine("        </dependency>");
            sb.AppendLine("");
            sb.AppendLine("        <dependency>");
            sb.AppendLine("            <groupId>org.springframework.cloud</groupId>");
            sb.AppendLine("            <artifactId>spring-cloud-starter-ribbon</artifactId>");
            sb.AppendLine("        </dependency>");
            sb.AppendLine("");
            sb.AppendLine("        <dependency>");
            sb.AppendLine("            <groupId>org.springframework.cloud</groupId>");
            sb.AppendLine("            <artifactId>spring-cloud-starter-hystrix</artifactId>");
            sb.AppendLine("        </dependency>");
            sb.AppendLine("");
            sb.AppendLine("        <!-- spring boot test-->");
            sb.AppendLine("        <dependency>");
            sb.AppendLine("            <groupId>org.springframework.boot</groupId>");
            sb.AppendLine("            <artifactId>spring-boot-starter-test</artifactId>");
            sb.AppendLine("            <scope>test</scope>");
            sb.AppendLine("        </dependency>");
            sb.AppendLine("    </dependencies>");

            sb.AppendLine("</project>");


            return sb;
        }

        private static StringBuilder GenWebApplication(ProjectConfig projectConfig, string basePath)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("package com.ydtech." + projectConfig.artifactId.ToLower() + "web;");
            sb.AppendLine("");
            sb.AppendLine("import org.springframework.boot.SpringApplication;");
            sb.AppendLine("import org.springframework.boot.autoconfigure.SpringBootApplication;");
            sb.AppendLine("import org.springframework.cloud.client.loadbalancer.LoadBalanced;");
            sb.AppendLine("import org.springframework.cloud.netflix.eureka.EnableEurekaClient;");
            sb.AppendLine("import org.springframework.cloud.netflix.hystrix.EnableHystrix;");
            sb.AppendLine("import org.springframework.context.annotation.Bean;");
            sb.AppendLine("import org.springframework.web.client.RestTemplate;");
            sb.AppendLine("");
            sb.AppendLine("@SpringBootApplication");
            sb.AppendLine("@EnableEurekaClient");
            sb.AppendLine("@EnableHystrix");
            sb.AppendLine("public class " + UnderscoreCamelUtil.ToPascalCase(projectConfig.artifactId) + "WebApplication {");
            sb.AppendLine("    public static void main(String[] args) {");
            sb.AppendLine("        SpringApplication.run(" + UnderscoreCamelUtil.ToPascalCase(projectConfig.artifactId) + "WebApplication.class, args);");
            sb.AppendLine("    }");
            sb.AppendLine("");
            sb.AppendLine("    @Bean");
            sb.AppendLine("    @LoadBalanced");
            sb.AppendLine("    public RestTemplate restTemplate(){");
            sb.AppendLine("        return new RestTemplate();");
            sb.AppendLine("    }");
            sb.AppendLine("}");
            sb.AppendLine("");
            
            return sb;
        }

        private static StringBuilder GenWebHiController(ProjectConfig projectConfig, string basePath)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("package com.ydtech." + projectConfig.artifactId.ToLower() + "web.controller;");
            sb.AppendLine("");
            sb.AppendLine("import com.ydtech." + projectConfig.artifactId.ToLower() + "web.service.HiService;");
            sb.AppendLine("import org.springframework.beans.factory.annotation.Autowired;");
            sb.AppendLine("import org.springframework.stereotype.Controller;");
            sb.AppendLine("import org.springframework.web.bind.annotation.GetMapping;");
            sb.AppendLine("import org.springframework.web.bind.annotation.PathVariable;");
            sb.AppendLine("import org.springframework.web.bind.annotation.RestController;");
            sb.AppendLine("");
            sb.AppendLine("@RestController");
            sb.AppendLine("public class HiController {");
            sb.AppendLine("    @Autowired");
            sb.AppendLine("    HiService hiService;");
            sb.AppendLine("");
            sb.AppendLine("    @GetMapping(\"/hi/{userName}\")");
            sb.AppendLine("    public String sayHiToUser(@PathVariable(\"userName\") String userName){");
            sb.AppendLine("        return hiService.sayHi(userName);");
            sb.AppendLine("    }");
            sb.AppendLine("}");

            return sb;
        }

        private static StringBuilder GenWebHiService(ProjectConfig projectConfig, string basePath)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("package com.ydtech." + projectConfig.artifactId.ToLower() + "web.service;");
            sb.AppendLine("");
            sb.AppendLine("import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;");
            sb.AppendLine("import org.springframework.beans.factory.annotation.Autowired;");
            sb.AppendLine("import org.springframework.stereotype.Service;");
            sb.AppendLine("import org.springframework.web.client.RestTemplate;");
            sb.AppendLine("");
            sb.AppendLine("@Service");
            sb.AppendLine("public class HiService {");
            sb.AppendLine("    String baseUrl = \"http://" + projectConfig.artifactId.ToLower() + "-service\";");
            sb.AppendLine("    ");
            sb.AppendLine("    @Autowired");
            sb.AppendLine("    RestTemplate restTemplate;");
            sb.AppendLine("");
            sb.AppendLine("");
            sb.AppendLine("    @HystrixCommand(fallbackMethod = \"sayHiError\")");
            sb.AppendLine("    public String sayHi(String userName){");
            sb.AppendLine("        return restTemplate.getForObject(baseUrl + \"/hi/\" + userName, String.class);");
            sb.AppendLine("    }");
            sb.AppendLine("");
            sb.AppendLine("    public String sayHiError(String userName){");
            sb.AppendLine("        return \"hi \" + userName + \" error ...\";");
            sb.AppendLine("    }");
            sb.AppendLine("}");



            return sb;
        }

        public static StringBuilder GenWebApplicationYml(ProjectConfig projectConfig, string basePath)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("server:");
            sb.AppendLine("  port: 8040");
            sb.AppendLine("spring:");
            sb.AppendLine("  application:");
            sb.AppendLine("    name: " + projectConfig.artifactId.ToLower() + "-web");
            sb.AppendLine("eureka:");
            sb.AppendLine("  client:");
            sb.AppendLine("    service-url:");
            sb.AppendLine("      defaultZone: http://localhost:8020/eureka");
            sb.AppendLine("");



            return sb;
        }
    

    }
}
